package com.jhc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jhc.bo.UserSaveDetails;
import com.jhc.dto.*;
import com.jhc.entity.*;
import com.jhc.mapper.*;
import com.jhc.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhc.utils.CheckType;
import com.jhc.utils.JHC;
import com.jhc.vo.DateVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 自习检查  服务实现类
 * </p>
 *
 * @author zfm
 * @since 2019-12-03
 */
@Service
public class IseStudyInspectServiceImpl extends ServiceImpl<IseStudyInspectMapper, IseStudyInspect> implements IIseStudyInspectService {

    @Autowired
    private IseStudyInspectMapper studyInspectMapper;

    @Autowired
    private UserSaveDetails userSaveDetails;

    @Autowired
    private IseScheduleMapper scheduleMapper;

    @Autowired
    private IseInspectionMapper iseInspectionMapper;

    @Autowired
    private CmsTeacherMapper teacherMapper;

    @Autowired
    private BacClassMapper classMapper;

    @Autowired
    private BacStudyMapper studyMapper;

    @Autowired
    private BacCollegeMapper collegeMapper;

    @Autowired
    private BacMajorMapper majorMapper;

    @Autowired
    private IBacTermService termService;

    @Autowired
    private IIseDormInspectService dormInspectService;

    @Autowired
    private IseImagesMapper imagesMapper;

    @Autowired
    private IIseScheduleService scheduleService;

    @Autowired
    private IIseInspectionService inspectionService;

    @Autowired
    private ICmsTeacherService teacherService;

    @Autowired
    private CmsStudentMapper studentMapper;

    @Autowired
    private CmsUserMapper cmsUserMapper;

    @Autowired
    private CmsTeacherMapper cmsTeacherMapper;

    @Autowired
    private ICmsUserService cmsUserService;



    /**
     * 查询当前自习列表
     *
     * @param searchDto
     * @return
     */
    @Override
    public IPage<IseStudyInspectViewDto> getStudyInspect(IseStudyInspectSearchDto searchDto) {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回null
        if (schedule == null){
            return new Page<>(searchDto.getCurrentPage(),searchDto.getPageSize());
        }
        //查询教学列表已检查对象id
        List<Object> itemCheckIds = inspectionService.getItemIds(nowDate,CheckType.ISESTUDY.getCode());
        if (itemCheckIds.size()==0&&searchDto.getIsWrited()!=null&&searchDto.getIsWrited()){
            return new Page<>(searchDto.getCurrentPage(),searchDto.getPageSize());
        }
        //分页查询自习列表
        Page page = new Page(searchDto.getCurrentPage(),searchDto.getPageSize());
        IPage<IseStudyInspectViewDto> studyDtoPage = studyInspectMapper.selectByIseStudyInspectSearchDto(page,searchDto,itemCheckIds);
        //标记是否已填写
        studyDtoPage.getRecords().stream().forEach(item ->{
            if (itemCheckIds.size()!=0&&itemCheckIds.contains(item.getId())){
                item.setIsWrited(true);
                IseInspection inspection = iseInspectionMapper.selectOne(new QueryWrapper<IseInspection>().lambda()
                        .eq(IseInspection::getItemCheckId,item.getId())
                        .eq(IseInspection::getDutyDate,JHC.toDateString(nowDate))
                        .eq(IseInspection::getCheckType,CheckType.ISESTUDY.getCode()));
                item.setInspectId(inspection.getId());
            }
            //拼接周次
            item.setWeek(schedule.getWeek());
        });
        return studyDtoPage;
    }

    /**
     * 查询自习检查进度条
     *
     * @return
     */
    @Override
    public Map<String, Object> getProgress() {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回null
        if (schedule == null){
            return null;
        }
        //查询自习列表数据条数
        Integer allStudyInspect = studyMapper.selectCount(null);
        //查询检查总表数据条数
        Integer finishStudyInspect = iseInspectionMapper.selectCount(new QueryWrapper<IseInspection>().lambda()
                .eq(IseInspection::getDutyDate,JHC.toDateString(new Date()))
                .eq(IseInspection::getCheckType,CheckType.ISESTUDY.getCode()));
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("allProgress",allStudyInspect);
        resultMap.put("finishProgress",finishStudyInspect);
        return resultMap;
    }


    /**
     * 查询当前自习列表(mp方式)
     *
     * @param searchDto
     * @return
     */
    @Override
    public IPage<IseStudyInspectViewDto> getStudyInspect2(IseStudyInspectSearchDto searchDto) {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回null
        if (schedule == null){
            return new Page<>(searchDto.getCurrentPage(),searchDto.getPageSize());
        }
        //查询教学列表已检查id
        List<Object> itemCheckIds = inspectionService.getItemIds(nowDate,30);
        //查询筛选条件
        //查询班主任列表
        List<String> teachList = cmsUserService.getUserListByLikeName(searchDto.getTeacherName())
                .stream().map(item -> item.getNumber()).collect(Collectors.toList());
        teachList.add(String.valueOf(0));
        //查询班级列表
        List<Object> classList = classMapper.selectObjs(new QueryWrapper<BacClass>().lambda().select(BacClass::getId)
                .in(searchDto.getTeacherName()!=null,BacClass::getAdviserNumber,teachList)
                .like(searchDto.getClassName()!=null,BacClass::getName,searchDto.getClassName()));
        classList.add(0);
        Page page = new Page(searchDto.getCurrentPage(),searchDto.getPageSize());
        Boolean iswrited = searchDto.getIsWrited();
//        IPage<IseStudyInspectViewDto> studyDtoPage = studyInspectMapper.selectByIseStudyInspectSearchDto(page,searchDto,itemCheckIds);
        IPage<BacStudy> studyIPage = studyMapper.selectPage(page,new QueryWrapper<BacStudy>().lambda()
                .in(iswrited!=null&&iswrited,BacStudy::getId,itemCheckIds)
                .notIn(iswrited!=null&&!iswrited,BacStudy::getId,itemCheckIds)
                .in(BacStudy::getClassId,classList));
        //标记是否已填写
        List<IseStudyInspectViewDto> viewDtos = new ArrayList<>();
        studyIPage.getRecords().stream().forEach(item ->{
            IseStudyInspectViewDto viewDto = new IseStudyInspectViewDto();
            BeanUtils.copyProperties(item,viewDto);
            if (itemCheckIds.contains(item.getId())){
                viewDto.setIsWrited(true);
            }
            BacClass classDto = classMapper.selectOne(new QueryWrapper<BacClass>().lambda()
                    .eq(BacClass::getId,item.getClassId()));
            viewDto.setClassName(classDto.getName());
            viewDto.setCollegeName(collegeMapper.selectOne(new QueryWrapper<BacCollege>().lambda()
                    .eq(BacCollege::getNumber,classDto.getCollegeNumber())).getName());
            viewDto.setAdviserNumber(classDto.getAdviserNumber());
            viewDto.setTeacherName(cmsUserMapper.selectOne(new QueryWrapper<CmsUser>().lambda()
                    .eq(CmsUser::getNumber,classDto.getAdviserNumber())).getName());
            viewDto.setProfessionalName(majorMapper.selectOne(new QueryWrapper<BacMajor>().lambda()
                    .eq(BacMajor::getNumber,classDto.getMajorNumber())).getProfessionalName());
            viewDtos.add(viewDto);
        });
        IPage<IseStudyInspectViewDto> viewDtoIPage = new Page<>();
        BeanUtils.copyProperties(studyIPage,viewDtoIPage);
        viewDtoIPage.setRecords(viewDtos);
        return viewDtoIPage;
    }

    /**
     * 查询已填写检查列表
     *
     * @param searchDto
     * @param type
     * @return
     */
    @Override
    public IPage<FinishStudyViewDto> getFinishStudy(AllStudySearchDto searchDto, Boolean type) {
        //获取当前用户名
        String username = null;
        String feedback = null;
        if (type!=null&&type){
            username = userSaveDetails.getCmsUser().getNumber();
        }
        if (type == null){
            feedback = userSaveDetails.getCmsUser().getNumber();
        }
        //获取当前学期开始和结束时间
        Date date = new Date();
        DateVo dateVo = termService.getTermDate(date);
        if (searchDto.getStartDate()==null){
            searchDto.setStartDate(dateVo.getStartDate());
        }
        if (searchDto.getEndDate()==null){
            searchDto.setEndDate(dateVo.getEndDate());
        }
        //查询默认当前学期信息
        Page page = new Page(searchDto.getCurrentPage(),searchDto.getPageSize());
        IPage<FinishStudyViewDto> viewDtoIPage = studyInspectMapper.selectByFinishStudySearchDto(page,searchDto,username,feedback);
        return viewDtoIPage;
    }

    /**
     * 查询详细自习检查信息(检查总表id查询)
     *
     * @param id
     * @return
     */
    @Override
    public DetailStudyViewDto getDetailStudyInspect(Long id) {
        DetailStudyViewDto viewDto = new DetailStudyViewDto();
        //查询自习检查表
        IseStudyInspect studyInspect = studyInspectMapper.selectOne(new QueryWrapper<IseStudyInspect>().lambda()
                .eq(IseStudyInspect::getInspectId,id));
        //查询检查总表
        IseInspection inspection = iseInspectionMapper.selectById(id);
        //查询自习表
        BacStudy study = studyMapper.selectById(inspection.getItemCheckId());
        //查询班级表
        BacClass bacClass = classMapper.selectById(study.getClassId());

        BeanUtils.copyProperties(studyInspect,viewDto);
        BeanUtils.copyProperties(inspection,viewDto);

        viewDto.setRoomName(study.getRoomName());
        viewDto.setRoomName(study.getRoomName());
        viewDto.setClassName(bacClass.getName());
        viewDto.setAdviserNumber(bacClass.getAdviserNumber());
        viewDto.setDutyNumber(inspection.getDutyTeacher());
        viewDto.setDutyName(cmsUserMapper.selectOne(new QueryWrapper<CmsUser>().lambda().eq(CmsUser::getNumber,inspection.getDutyTeacher())).getName());
        viewDto.setCollegeName(collegeMapper.selectOne(new QueryWrapper<BacCollege>().lambda().eq(BacCollege::getNumber,bacClass.getCollegeNumber())).getName());
        viewDto.setProfessionalName(majorMapper.selectOne(new QueryWrapper<BacMajor>().lambda().eq(BacMajor::getNumber,bacClass.getMajorNumber())).getProfessionalName());
        viewDto.setTeacherName(cmsUserMapper.selectOne(new QueryWrapper<CmsUser>().lambda().eq(CmsUser::getNumber,bacClass.getAdviserNumber())).getName());
        //拼接多个老师字符串
        viewDto.setTeaNumbers(dormInspectService.getTeachersStr(inspection.getTeachersNumbers()));
        viewDto.setId(studyInspect.getId());
        //查询图片
        IseImages images = imagesMapper.selectOne(new QueryWrapper<IseImages>().lambda().eq(IseImages::getInspectId,inspection.getId()));
        if (images!=null){
            viewDto.setImage(images.getAddress());
        }else {
            viewDto.setImage(null);
        }
        return viewDto;
    }

    /**
     * 填写自习反馈(检查总表id查询)
     *
     * @param feedBackAddDto
     * @return
     */
    @Override
    public Boolean addFeedbackStudy(FeedBackAddDto feedBackAddDto) {
//        IseStudyInspect studyInspect = studyInspectMapper.selectById(feedBackAddDto.getId());
//        if (studyInspect == null){
//            return false;
//        }
        //查询检查列表
        IseInspection inspection = iseInspectionMapper.selectById(feedBackAddDto.getId());
        //判断是否需要填写
        if (inspection == null||inspection.getFeedbackStatus()==10){
            return false;
        }
        //获取当前登录用户编号
        String username = userSaveDetails.getCmsUser().getNumber();
        //获取责任人用户编号
        BacStudy study = studyMapper.selectById(inspection.getItemCheckId());
        String feedbacker = classMapper.selectById(study.getClassId()).getAdviserNumber();
        if (!username.equals(feedbacker)){
            return false;
        }

        inspection.setFeedbackStatus(20);
        inspection.setResult(feedBackAddDto.getResult());
        iseInspectionMapper.updateById(inspection);
        return true;
    }

    /**
     * 填写自习检查
     *
     * @param addDto
     * @return
     */
    @Override
    public Map<String,Object> addStudyInspect(IseStudyInspectAddDto addDto) {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回false
        if (schedule == null){
            return null;
        }
        //查询检查对象列表，查看有无记录
        BacStudy study = studyMapper.selectById(addDto.getId());
        if (study==null){
            return null;
        }
        BacClass bacClass = classMapper.selectById(study.getClassId());
        //查询检查总表，查看有无记录
        List<IseInspection> inspectionList = inspectionService.getInspections(nowDate,addDto.getId(),30);
        if (inspectionList.size()>0){
            return null;
        }
        //遍历相关教师，校验数据
        addDto.setTeaNumbers(addDto.getTeaNumbers().stream().distinct().collect(Collectors.toList()));
        if (!cmsUserService.isUserNumberList(addDto.getTeaNumbers())){
            return null;
        }

        //构造检查总表插入对象
        InspectionCreateDto createDto = new InspectionCreateDto(schedule.getWeek(),nowDate,username, CheckType.ISESTUDY.getCode());
        BeanUtils.copyProperties(addDto,createDto);
        Map<String,Object> resultMap = inspectionService.addInspection(createDto,bacClass.getAdviserNumber());
        IseInspection inspection = (IseInspection) resultMap.get("inspection");
        //构造自习检查表插入对象
        IseStudyInspect studyInspect = new IseStudyInspect();
        BeanUtils.copyProperties(addDto,studyInspect);
        studyInspect.setImage(null);
        studyInspect.setId(null);
        studyInspect.setInspectId(inspection.getId());
        studyInspectMapper.insert(studyInspect);
        //构造图片插入对象
        if (addDto.getImage()!=null&&StringUtils.isNotBlank(addDto.getImage())){
            IseImages iseImages = new IseImages();
            iseImages.setAddress(addDto.getImage());
            iseImages.setInspectId(inspection.getId());
            imagesMapper.insert(iseImages);
        }
        Map<String,Object> trueAndMsg = new HashMap<>();
        trueAndMsg.put("msgList",resultMap.get("msgList"));
        return trueAndMsg;
    }

    /**
     * 修改自习检查
     *
     * @param updateDto
     * @return
     */
    @Override
    public Boolean updateStudyInspect(IseStudyInspectUpdateDto updateDto) {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回false
        if (schedule == null){
            return false;
        }
        //查询检查总表，查看是否有记录
        IseInspection iseInspection = iseInspectionMapper.selectById(updateDto.getInspectId());
        if (iseInspection == null||!iseInspection.getDutyDate().equals(nowDate)){
            return false;
        }
        //遍历相关教师，校验数据
        updateDto.setTeaNumbers(updateDto.getTeaNumbers().stream().distinct().collect(Collectors.toList()));
        if (!cmsUserService.isUserNumberList(updateDto.getTeaNumbers())){
            return false;
        }
        //封装对象数据，更新数据
        BeanUtil.copyProperties(updateDto,iseInspection, CopyOptions.create().setIgnoreNullValue(true));
        iseInspection.setTeachersNumbers(JSON.toJSONString(updateDto.getTeaNumbers()));
        iseInspection.setDutyTeacher(username);
        iseInspection.setUpdateTime(null);
        iseInspectionMapper.updateById(iseInspection);
        //查询自习检查表
        IseStudyInspect studyInspect = studyInspectMapper.selectOne(new QueryWrapper<IseStudyInspect>().lambda()
                .eq(IseStudyInspect::getInspectId,updateDto.getInspectId()));
        if (studyInspect==null){
            return false;
        }
        BeanUtil.copyProperties(updateDto,studyInspect,CopyOptions.create().setIgnoreNullValue(true));
        studyInspect.setUpdateTime(null);
        studyInspectMapper.updateById(studyInspect);
        //查询检查图片
        if (updateDto.getImageAddress()==null||!StringUtils.isNotBlank(updateDto.getImageAddress())){
            return true;
        }
        IseImages images = imagesMapper.selectOne(new QueryWrapper<IseImages>().lambda()
                .eq(IseImages::getInspectId,iseInspection.getId()));
        if (images==null){
            images = new IseImages();
            images.setAddress(updateDto.getImageAddress());
            images.setInspectId(iseInspection.getId());
            imagesMapper.insert(images);
            return true;
        }
        images.setAddress(updateDto.getImageAddress());
        images.setUpdateTime(null);
        imagesMapper.updateById(images);
        return true;
    }

    /**
     * 查询自习数据分析
     *
     * @param searchDto
     * @return
     */
    @Override
    public List<AnalysisStudyViewDto> getAnalysis(AnalysisSearchDto searchDto) {
        CmsUser teacher = userSaveDetails.getCmsUser();
        //查询班主任所在班级id
        List<Object> classIds = classMapper.selectObjs(new QueryWrapper<BacClass>().lambda()
                .select(BacClass::getId)
                .eq(BacClass::getAdviserNumber,teacher.getNumber()));
        if (classIds.size()==0){
            return new ArrayList<>();
        }
        //判断查询条件classId
        if (searchDto.getClassId()!=null){
            if (!classIds.contains(searchDto.getClassId())){
                return new ArrayList<>();
            }
            classIds.clear();
            classIds.add(searchDto.getClassId());
        }
        return analysisStudy(classIds,searchDto);
    }

    /**
     * 计算自习检查的分析数据
     *
     * @param classIds
     * @param searchDto
     * @return
     */
    @Override
    public List<AnalysisStudyViewDto> analysisStudy(List<Object> classIds, AnalysisSearchDto searchDto) {
        //定义返回对象
        List<AnalysisStudyViewDto> viewDtoList = new ArrayList<>();
        classIds.stream().forEach(classId -> {
            //查询班级信息
            BacClass bacClass = classMapper.selectOne(new QueryWrapper<BacClass>().lambda()
                    .eq(BacClass::getId,classId));

            AnalysisStudyViewDto viewDto = new AnalysisStudyViewDto();

            viewDto.setClassId(bacClass.getId());
            viewDto.setClassName(bacClass.getName());
            //查询自习表
            BacStudy study = studyMapper.selectOne(new QueryWrapper<BacStudy>().lambda()
                    .eq(BacStudy::getClassId,classId));
            if (study == null){
                viewDtoList.add(viewDto);
                return;
            }
            List<Object> studyIds = new ArrayList<>();
            studyIds.add(study.getId());
            //查询检查总表
            List<IseInspection> inspectionList = inspectionService.getInspections(searchDto.getStartDate(),searchDto.getEndDate(),studyIds,CheckType.ISESTUDY.getCode());
            if (inspectionList.size()==0){
                viewDtoList.add(viewDto);
                return;
            }
            List<Long> inspectIds = inspectionList.stream().map(item -> item.getId()).collect(Collectors.toList());
            System.out.println(inspectIds);
            //查询自习检查表
            List<IseStudyInspect> studyInspectList = studyInspectMapper.selectList(new QueryWrapper<IseStudyInspect>().lambda()
                    .in(IseStudyInspect::getInspectId,inspectIds));
            studyInspectList.stream().forEach(studyInspect -> {
                viewDto.addAnalysis(studyInspect);
            });
            viewDtoList.add(viewDto);
        });
        return viewDtoList;
    }

    /**
     * 查询自习应到人数(对象id使用)
     *
     * @param id
     * @return
     */
    @Override
    public Integer getStudyCount(Long id) {
        //查询自习信息
        BacStudy bacStudy = studyMapper.selectById(id);
        return studentMapper.selectCount(new QueryWrapper<CmsStudent>().lambda()
                .eq(CmsStudent::getClassId,bacStudy.getClassId()));
    }

    /**
     * 查询自习应到人数(检查总表id使用)
     *
     * @param id
     * @return
     */
    @Override
    public Integer getStudyCountByInspectId(Long id) {
        //查询检查总表信息
        IseInspection inspection = iseInspectionMapper.selectById(id);
        //查询自习表信息
        BacStudy bacStudy = studyMapper.selectById(inspection.getItemCheckId());
        //查询学生人数
        return studentMapper.selectCount(new QueryWrapper<CmsStudent>().lambda()
                .eq(CmsStudent::getClassId,bacStudy.getClassId()));
    }
}
